#ifndef __THREAD_POOL__
#define __THREAD_POOL__
#include "tidArr.h"
#include "taskQueue.h"
#include <sys/epoll.h>
#include <unistd.h>
#include "dir_stack.h"
#include "mysql.h"
#include <math.h>
#include "log.h"
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <openssl/sha.h>
#include <openssl/opensslv.h>
#include <openssl/evp.h>

typedef struct threadPool_s{
    //子线程信息
    tidArr_t tidArr;    
    //任务队列
    taskQueue_t taskQueue;
    //锁
    pthread_mutex_t mutex;
    //条件变量
    pthread_cond_t cond;
    //退出标志
    int exitflag;
}threadPool_t;
//线程tcp  ip和端口的初始化
int tcpInit(int* sockfd,char* ip,char* port);
//创建子线程
int makeWorker(threadPool_t* pthreadPool);
//接收规则
int recvn(int netfd,void* pstart,int len);
//处理任务
int deal(int netfd,char* client_ip);
//任务队列,线程,锁,条件变量 --初始化
int threadPoolInit(threadPool_t* pthreadPool,int workNum);
//添加一个监听
int epollAdd(int epfd, int fd);
//删除一个监听
int epollDel(int epfd,int fd);
// 检查命令行参数数量是否符合预期
#define ARGS_CHECK(argc, expected)\
    do { \
        if ((argc) != (expected)) { \
            fprintf(stderr, "args num error!\n"); \
            exit(1); \
        } \
    } while (0)

// 检查返回值是否是错误标记,若是则打印msg和错误信息
#define ERROR_CHECK(ret, error_flag, msg) \
    do { \
        if ((ret) == (error_flag)) { \
            perror(msg); \
            exit(1); \
        } \
    } while (0)
//第一版上传方的发送：hash,文件名,之后收一个返回值，服务端完成哈希查找是否文件已经存在，判断要不要后续再传
//      下载方的发送：filename

#define train_size (sizeof(train.type)+sizeof(train.length)+train.length)

typedef struct train{
    int type;
    int length;
    char arr[4096];
}train_t;

typedef struct file_message{                                                                                                                                                                                   
    char hash_file[1024];//最高支持sha256
    int transed_byte;
    int fd;
    char filename[1024];
}file_msg_t;
int init_train(train_t *train);

int init_file_msg(file_msg_t *msg);

int com_hash(MYSQL *mysql,file_msg_t *file_message);

int caculate_hash(char *filepath,char *sha);
int recv_train(int netfd,train_t *train);

int push_file(int netfd,char *filename,char* user,MYSQL *mysql,Link_list_t *catalog);
int recv_file(int netfd,MYSQL *mysql,Link_list_t *catalog,char user[]);

int up_file(int sockfd,char *filename);
int down_file(int sockfd,char *filename);

int insert_filetable(MYSQL *mysql,file_msg_t *file_message,char *user,Link_list_t *catalog,int flags);

int get_filepath(Link_list_t *catalog,char *path,char *filename);


#endif

